package com.cff.util;

import java.io.IOException;  
import java.io.InputStream;  
import java.io.PrintStream;  
import java.io.UnsupportedEncodingException;  
import java.net.SocketException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Properties;

import org.apache.commons.net.telnet.TelnetClient;  
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.jpre.packet.Coder;
import com.ums.common.hsm.HSM;
import com.ums.common.hsm.HSMException;
import com.ums.common.hsm.HSMExecutorServiceImpl;
import com.ums.common.hsm.HSMImpl;
  
/** 
 * Telnet操作器,基于commons-net-2.2.jar 
 * @author JiangKunpeng 
 * 
 */  
public class TelnetTools {  
	private static Properties confPro = null;
    private String prompt = ">"; //结束标识字符串,Windows中是>,Linux中是#  
    private char promptChar = '>';   //结束标识字符  
    private TelnetClient telnet;  
    private InputStream in;     // 输入流,接收返回信息  
    private PrintStream out;    // 向服务器写入 命令  
    private String hsmIp = "";
    private String hsmPort = "";
    private String destIp = "";
    private String destPort = "";
    
    HSMExecutorServiceImpl exec;
	HSMImpl hsm;

	
	public String getHsmIp() {
		return hsmIp;
	}

	public void setHsmIp(String hsmIp) {
		this.hsmIp = hsmIp;
	}

	public String getHsmPort() {
		return hsmPort;
	}

	public void setHsmPort(String hsmPort) {
		this.hsmPort = hsmPort;
	}

	public String getDestIp() {
		return destIp;
	}

	public void setDestIp(String destIp) {
		this.destIp = destIp;
	}

	public String getDestPort() {
		return destPort;
	}

	public void setDestPort(String destPort) {
		this.destPort = destPort;
	}

	@Before
	public void init() {
		confPro = FileUtil.getInstance();
		hsmIp = confPro.getProperty("hsmip");
		hsmPort = confPro.getProperty("hsmport");
		destIp = confPro.getProperty("app12ip");
		destPort = confPro.getProperty("app12port");
		exec = new HSMExecutorServiceImpl(new String[] { hsmIp+":"+hsmPort });
		exec.init();
		hsm = new HSMImpl();
		hsm.setExec(exec);
	}
	
	@After
	public void destroy() {
		exec.shutdown();
	}
	
    /** 
     * @param termtype  协议类型：VT100、VT52、VT220、VTNT、ANSI 
     * @param prompt    结果结束标识 
     */  
    public TelnetTools(){  
        telnet = new TelnetClient("VT220");  
        setPrompt(prompt);  
    }  
      
    /** 
     * 登录到目标主机 
     * @param ip 
     * @param port 
     * @param username 
     * @param password 
     * @throws IOException 
     * @throws SocketException 
     */  
    public void login(String ip, int port) throws SocketException, IOException{    
        telnet.connect(ip, port);  
        in = telnet.getInputStream();  
        out = new PrintStream(telnet.getOutputStream());           
    }  
      
    /** 
     * 读取分析结果 
     *  
     * @param pattern   匹配到该字符串时返回结果 
     * @return 
     */  
    public String readUntil(String pattern) {  
        StringBuffer sb = new StringBuffer();  
        try {  
            char lastChar = (char)-1;  
            boolean flag = pattern!=null&&pattern.length()>0;  
            if(flag)  
                lastChar = pattern.charAt(pattern.length() - 1);  
            char ch;  
            int code = -1;  
            while ((code = in.read()) != -1) {  
                ch = (char)code;  
                sb.append(ch);  
                  
                //匹配到结束标识时返回结果  
                if (flag) {  
                    if (ch == lastChar && sb.toString().endsWith(pattern)) {  
                        return sb.toString();  
                    }  
                }else{  
                    //如果没指定结束标识,匹配到默认结束标识字符时返回结果  
                    if(ch == promptChar)  
                        return sb.toString();  
                }  
                //登录失败时返回结果  
                if(sb.toString().contains("Login Failed")){  
                    return sb.toString();  
                }  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return sb.toString();  
    }  
      
    /** 
     * 发送命令 
     *  
     * @param value 
     */  
    public void write(String value) {  
        try {  
            out.println(value);  
            out.flush();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
      
    /** 
     * 发送命令,返回执行结果 
     *  
     * @param command 
     * @return 
     */  
    public String sendCommand(String command) {  
        try {  
            write(command);  
            return readUntil(prompt);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return null;  
    }  
      
    /** 
     * 关闭连接 
     */  
    public void distinct(){  
        try {  
            if(telnet!=null&&!telnet.isConnected())  
                telnet.disconnect();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
  
    public void setPrompt(String prompt) {  
        if(prompt!=null){  
            this.prompt = prompt;  
            this.promptChar = prompt.charAt(prompt.length()-1);  
        }  
    }  
    
    public String acct(String dataTmp) {  
    	TelnetTools telnet = new TelnetTools(); //Windows,用VT220,否则会乱码  
        try {
        	System.out.println(destIp+"  "+destPort);
			telnet.login(destIp, Integer.parseInt(destPort));
		} catch (NumberFormatException e1) {
			e1.printStackTrace();
		} catch (SocketException e1) {
			return "连接目标主机失败！";
		} catch (IOException e1) {
			e1.printStackTrace();
		}  
        String command = dataTmp;
        command = new DecimalFormat("000000").format(command.length())+command;
        String rs = telnet.sendCommand(command);  
        try {  
            rs = new String(rs.getBytes("ISO-8859-1"),"UTF-8");   //转一下编码  
        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
        }  
        System.out.println(rs);  
        
        return rs;
    }  
    
    public String trans(String dataTmp,TelnetTools telnet) {  
    	//TelnetTools telnet = new TelnetTools(); //Windows,用VT220,否则会乱码  
    	telnet.init();
    	System.out.println(telnet.hsmIp + "---" + telnet.hsmPort);
        try {
			telnet.login(destIp, Integer.parseInt(destPort));
		} catch (NumberFormatException e1) {
			e1.printStackTrace();
		} catch (SocketException e1) {
			return "连接目标主机失败！";
		} catch (IOException e1) {
			e1.printStackTrace();
		}  
        String rawdata = dataTmp;
       
        byte[] rs = rawdata.getBytes();	
        byte[] raw = new byte[rs.length];
        byte[] mackey = Coder.hexStr2byte(confPro.getProperty("app1key1"));				
		System.arraycopy(rs, 0, raw, 0, raw.length);
		for(int i=0;i<raw.length;i++)
			System.out.print(raw[i]+" ");
		System.out.println();
		for(int i=0;i<mackey.length;i++)
			System.out.print(mackey[i]+" ");
		System.out.println();
		
		byte[] mac = null;
		System.out.println("create raw data:" + new String(raw));
		System.out.println("create key:" + new String(Coder.BCD2ASC(mackey)));
		try {
			mac = telnet.hsm.genMACByLMKMAK(mackey, raw);
		} catch (HSMException e) {
			e.printStackTrace();
		}
		String macs = new String(Coder.BCD2ASC(mac));
		System.out.println("mac:"+macs);
		String data = rawdata+"|"+macs;
		data = new DecimalFormat("0000").format(data.length())+data;
		System.out.println("报文:"+data);
        String res = telnet.sendCommand(data);  
        try {  
            res = new String(res.getBytes("ISO-8859-1"),"UTF-8");   //转一下编码  
        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
        }  
        System.out.println(res);  
        telnet.destroy();
        return res;
    }
    
    /**
     * 发往任意端口
     * @throws SocketException
     * @throws IOException
     */
    public String allSend(String dataTmp,String mactext){  
    	TelnetTools telnet = new TelnetTools(); //Windows,用VT220,否则会乱码  
    	telnet.init();
        try {
			telnet.login(confPro.getProperty("app11ip"), Integer.parseInt(destPort));
		} catch (NumberFormatException e1) {
			e1.printStackTrace();
		} catch (SocketException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}  
        String rawdata = dataTmp;
        byte[] rs = rawdata.getBytes();	
        byte[] raw = new byte[rs.length];
        byte[] mackey = Coder.hexStr2byte(mactext);				
		System.arraycopy(rs, 0, raw, 0, raw.length);
		for(int i=0;i<raw.length;i++)
			System.out.print(raw[i]+" ");
		System.out.println();
		for(int i=0;i<mackey.length;i++)
			System.out.print(mackey[i]+" ");
		System.out.println();
		
		byte[] mac = null;
		System.out.println("create raw data:" + new String(raw));
		System.out.println("create key:" + new String(Coder.BCD2ASC(mackey)));
		try {
			mac = telnet.hsm.genMACByLMKMAK(mackey, raw);
		} catch (HSMException e) {
			e.printStackTrace();
		}
		String macs = new String(Coder.BCD2ASC(mac));
		System.out.println("mac:"+macs);
		String data = rawdata+"|"+macs;
		data = new DecimalFormat("0000").format(data.length())+data;
		System.out.println("报文:"+data);
        String res = telnet.sendCommand(data);  
        try {  
            res = new String(res.getBytes("ISO-8859-1"),"UTF-8");   //转一下编码  
        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
        }  
        System.out.println(res);  
        telnet.destroy();
        return res;
    } 
    
} 